﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using AppFabric.ServiceBus.Common;
using AppFabric.ServiceBus.CommonForms;

namespace AppFabricTestClient
{
    public partial class SendForm : Form
    {
        ServiceBusHelper helper = null;
        int messageCount = 0;
        bool isConnected = false;
        private BindingSource bindingSource = new BindingSource();

        public SendForm()
        {
            InitializeComponent();
            bindingSource.Add(new PropertyInfo{Key= "User", Value = System.Environment.UserName});
            dgvProperties.DataSource = bindingSource;
        }

        #region Private Methods
        private void connectToolStripMenuItem1_Click(object sender, EventArgs e)
        {
            if (!isConnected)
            {
                ConnectForm connectForm = new ConnectForm();
                connectForm.ShowDialog();
                if (connectForm.DialogResult == System.Windows.Forms.DialogResult.OK)
                {
                    try
                    {
                        ServiceBusNamespace token = new ServiceBusNamespace(connectForm.Namespace,
                                    connectForm.ServicePath,
                                    connectForm.IssuerName,
                                    connectForm.IssuerKey);
                        helper = new ServiceBusHelper();
                        helper.Token = token;
                        isConnected = helper.Connect();
                        connectToolStripMenuItem.Text = "Disconnect";
                    }
                    catch
                    {
                        MessageBox.Show("Test client was unable to Connect. Please enter correct credentials.");
                    }
                }
            }
            else
            {
                helper = null;
                isConnected = false;
                connectToolStripMenuItem.Text = "Connect";
            }
        }

        private void cboCommunicationObject_SelectedIndexChanged(object sender, EventArgs e)
        {
            if (!CheckConnection())
                return;
            gbCommunicationObject.Text = "Choose " + cboCommunicationObject.SelectedItem.ToString();
            try
            {
                lblStatus.Text = "Loading " + cboCommunicationObject.SelectedItem.ToString() + "s from Namespace...";
                switch (cboCommunicationObject.SelectedItem.ToString())
                {
                    case "Queue":
                        {
                            cboDescriptions.DataSource = helper.GetQueues().Select(p => p.Path).ToList();
                            break;
                        }
                    case "Topic":
                        {
                            cboDescriptions.DataSource = helper.GetTopics().Select(p => p.Path).ToList();
                            break;
                        }
                }
                lblStatus.Text = "Completed";
            }
            catch 
            {
                MessageBox.Show("Test client was unable to fetch " + cboCommunicationObject.SelectedItem.ToString() + "s");
                lblStatus.Text = "Error Occured";
            }
        }

        private void btnCancel_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void btnOk_Click(object sender, EventArgs e)
        {
            if (!CheckConnection())
                return;
            if (!ValidateMessageControls())
                return;
            try
            {
                MessageSettings settings = GetMessageSettings();
                lblStatus.Text = "Sending Message...";
                switch (cboCommunicationObject.SelectedItem.ToString())
                {
                    case "Queue":
                        {
                            helper.SendMessageToQueue(rtbPayLoad.Text, cboDescriptions.SelectedItem.ToString(), settings);
                            break;
                        }
                    case "Topic":
                        {
                            helper.SendMessageToTopic(rtbPayLoad.Text, cboDescriptions.SelectedItem.ToString(), settings);
                            break;
                        }
                }
                ++messageCount;
                lblMessageCount.Text = "Message Count: " + messageCount.ToString();
                lblStatus.Text = "Message Sent";
            }
            catch(Exception ex)
            {
                MessageBox.Show("Test client was unable to send a message. Please contact Administrator.");
                lblStatus.Text = "Error occured";
            }
           
        }

        private void exitToolStripMenuItem_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private bool CheckConnection()
        {
            if (!isConnected)
            {
                MessageBox.Show("Please Connect to Windows AppFabric ServiceBus first.");
            }
            return isConnected;
        }

        private MessageSettings GetMessageSettings()
        {
            MessageSettings settings = new MessageSettings();
            settings.ContentType = txtContentType.Text;
            settings.CorrelationId = txtCorrelationId.Text;
            settings.Label = txtLabel.Text;
            settings.SessionId = txtSessionId.Text;
            settings.MessageId = txtMessageId.Text;
            if (!string.IsNullOrEmpty(txtTTL.Text))
            {
                int seconds = int.Parse(txtTTL.Text);
                settings.TimeToLive = TimeSpan.FromSeconds(seconds);
            }
            var properties = ((System.Windows.Forms.BindingSource)(dgvProperties.DataSource)).List;
            if (properties.Count > 0)
            {
                settings.MessageProperties = new Dictionary<string, object>();
            }
            foreach (PropertyInfo property in properties)
            {
                if (!string.IsNullOrEmpty(property.Key) && !string.IsNullOrEmpty(property.Value))
                {
                    settings.MessageProperties.Add(property.Key, property.Value);
                }
            }
            return settings;
        }

        private bool ValidateMessageControls()
        {
            bool result = true;
            if (cboCommunicationObject.SelectedItem == null)
            {
                MessageBox.Show("Please choose Communication Object.");
                result = false;
            }
            else
            {
                if (cboCommunicationObject.SelectedItem.ToString() == "Topic")
                {
                    if (cboDescriptions.Items.Count == 0)
                    {
                        MessageBox.Show("No Topics present in Namespace.");
                        result = false;
                    }
                }
                else
                {
                    if (cboDescriptions.Items.Count == 0)
                    {
                        MessageBox.Show("No Queues present in Namespace.");
                        result = false;
                    }
                }
            }
            if (string.IsNullOrEmpty(rtbPayLoad.Text))
            {
                MessageBox.Show("Please enter a message to send");
                result = false;
            }
            if (!string.IsNullOrEmpty(txtTTL.Text))
            {
                int sec;
                if (!int.TryParse(txtTTL.Text, out sec))
                {
                    MessageBox.Show("Please enter positive numeric value for Time To Live");
                    result = false;
                }
                else
                {
                    if (sec == 0)
                    {
                        MessageBox.Show("Please enter positive numeric value for Time To Live");
                        result = false;
                    }
                }
            }
            return result;
        }
        #endregion
    }
}
